using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace DeviceCommons
{
    /// <summary>
    /// DeviceCommons配置服务接口
    /// </summary>
    public interface IDeviceCommonsConfigurationService
    {
        /// <summary>
        /// 获取当前配置选项
        /// </summary>
        DeviceCommonsOptions CurrentOptions { get; }

        /// <summary>
        /// 获取加密函数
        /// </summary>
        Func<string, string>? EncryptFunc { get; }

        /// <summary>
        /// 获取解密函数
        /// </summary>
        Func<string, string>? DecryptFunc { get; }

        /// <summary>
        /// 获取压缩函数
        /// </summary>
        Func<byte[], byte[]>? CompressFunc { get; }

        /// <summary>
        /// 获取解压函数
        /// </summary>
        Func<byte[], byte[]>? DecompressFunc { get; }

        /// <summary>
        /// 是否启用了加密
        /// </summary>
        bool IsEncryptionEnabled { get; }

        /// <summary>
        /// 是否启用了压缩
        /// </summary>
        bool IsCompressEnabled { get; }
    }

    /// <summary>
    /// DeviceCommons配置服务实现
    /// </summary>
    internal class DeviceCommonsConfigurationService : IDeviceCommonsConfigurationService
    {
        private readonly IOptionsMonitor<DeviceCommonsOptions> _optionsMonitor;
        private readonly Lazy<Func<string, string>?> _encryptFunc;
        private readonly Lazy<Func<string, string>?> _decryptFunc;
        private readonly Lazy<Func<byte[], byte[]>?> _compressFunc;
        private readonly Lazy<Func<byte[], byte[]>?> _decompressFunc;

        public DeviceCommonsConfigurationService(
            IOptionsMonitor<DeviceCommonsOptions> optionsMonitor,
            IServiceProvider serviceProvider)
        {
            _optionsMonitor = optionsMonitor;

            _encryptFunc = new Lazy<Func<string, string>?>(() => CreateEncryptFunction(serviceProvider));
            _decryptFunc = new Lazy<Func<string, string>?>(() => CreateDecryptFunction(serviceProvider));

            _compressFunc = new Lazy<Func<byte[], byte[]>?>(() => CreateCompressFunction(serviceProvider));
            _decompressFunc = new Lazy<Func<byte[], byte[]>?>(() => CreateDecompressFunction(serviceProvider));
        }

        public DeviceCommonsOptions CurrentOptions => _optionsMonitor.CurrentValue;

        public Func<string, string>? EncryptFunc => _encryptFunc.Value;

        public Func<string, string>? DecryptFunc => _decryptFunc.Value;

        public Func<byte[], byte[]>? CompressFunc => _compressFunc.Value;

        public Func<byte[], byte[]>? DecompressFunc => _decompressFunc.Value;

        public bool IsEncryptionEnabled =>
            CurrentOptions.EnableDefaultAesEncryption ||
            CurrentOptions.EncryptFunc != null;

        public bool IsCompressEnabled =>
            CurrentOptions.EnableDefaultGZipCompression ||
            CurrentOptions.CompressFunc != null;

        private Func<byte[], byte[]>? CreateCompressFunction(IServiceProvider serviceProvider)
        {
            var options = CurrentOptions;

            // 优先使用自定义压缩函数
            if (options.CompressFunc != null)
            {
                return options.CompressFunc;
            }

            // 使用默认GZip压缩
            if (options.EnableDefaultGZipCompression)
            {
                var gzip = serviceProvider.GetRequiredService<DataHandling.Compression.Compressor>();
                return compressedData => gzip.Compress(compressedData);
            }

            return null;
        }

        private Func<byte[], byte[]>? CreateDecompressFunction(IServiceProvider serviceProvider)
        {
            var options = CurrentOptions;

            // 优先使用自定义解压函数
            if (options.DecompressFunc != null)
            {
                return options.DecompressFunc;
            }

            // 使用默认GZip解压
            if (options.EnableDefaultGZipCompression)
            {
                var gzip = serviceProvider.GetRequiredService<DataHandling.Compression.Compressor>();
                return compressedData => gzip.Decompress(compressedData);
            }

            return null;
        }

        private Func<string, string>? CreateEncryptFunction(IServiceProvider serviceProvider)
        {
            var options = CurrentOptions;

            // 优先使用自定义加密函数
            if (options.EncryptFunc != null)
            {
                return options.EncryptFunc;
            }

            // 使用默认AES加密
            if (options.EnableDefaultAesEncryption && !string.IsNullOrEmpty(options.DefaultEncryptionPassword))
            {
                // 根据配置的AES模式创建相应的加密器实例
                var aes = options.AesEncryptionMode switch
                {
                    AesMode.Fast => Security.AesEncryptor.CreateFastMode(),
                    AesMode.Secure => Security.AesEncryptor.CreateSecureMode(),
                    _ => Security.AesEncryptor.CreateFastMode() // 默认使用快速模式
                };
                
                return plainText => aes.Encrypt(plainText, options.DefaultEncryptionPassword);
            }

            return null;
        }

        private Func<string, string>? CreateDecryptFunction(IServiceProvider serviceProvider)
        {
            var options = CurrentOptions;

            // 优先使用自定义解密函数
            if (options.DecryptFunc != null)
            {
                return options.DecryptFunc;
            }

            // 使用默认AES解密
            if (options.EnableDefaultAesEncryption && !string.IsNullOrEmpty(options.DefaultEncryptionPassword))
            {
                // 根据配置的AES模式创建相应的加密器实例
                var aes = options.AesEncryptionMode switch
                {
                    AesMode.Fast => Security.AesEncryptor.CreateFastMode(),
                    AesMode.Secure => Security.AesEncryptor.CreateSecureMode(),
                    _ => Security.AesEncryptor.CreateFastMode() // 默认使用快速模式
                };
                
                return cipherText => aes.Decrypt(cipherText, options.DefaultEncryptionPassword);
            }

            return null;
        }
    }
}